package com.pearadmin.modules.sys.controller.app;

import cn.hutool.core.bean.BeanUtil;
import com.github.pagehelper.PageInfo;
import com.pearadmin.common.config.proprety.TemplateProperty;
import com.pearadmin.common.constant.CommonConstant;
import com.pearadmin.common.constant.ControllerConstant;
import com.pearadmin.common.exception.base.BusinessException;
import com.pearadmin.common.plugin.logging.aop.annotation.Logging;
import com.pearadmin.common.secure.utils.JwtUtils;
import com.pearadmin.common.tools.SequenceUtil;
import com.pearadmin.common.tools.ServletUtil;
import com.pearadmin.common.tools.string.Convert;
import com.pearadmin.common.tools.string.StringUtil;
import com.pearadmin.common.web.base.BaseController;
import com.pearadmin.common.web.domain.request.PageDomain;
import com.pearadmin.common.web.domain.response.Result;
import com.pearadmin.common.web.domain.response.module.ResultTable;
import com.pearadmin.modules.sys.domain.*;
import com.pearadmin.modules.sys.domain.dto.NoticeStatus;
import com.pearadmin.modules.sys.domain.dto.OperateAnodeDto;
import com.pearadmin.modules.sys.domain.dto.WorkCleanDto;
import com.pearadmin.modules.sys.domain.dto.WorkFixDto;
import com.pearadmin.modules.sys.domain.vo.*;
import com.pearadmin.modules.sys.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: Mr.ling
 * @data: 2021/12/9
 * @apiNote
 */
@RestController
@RequestMapping(ControllerConstant.API_APP_PREFIX)
@Api(tags = {"APP移动端接口"})
@Slf4j
public class AppController extends BaseController {

    // 碳块工作记录
    private final static String BLOCK_PREFIX = "work/block/";
    // 车队工作记录
    private final static String CAR_PREFIX = "work/car/";
    // 检修工作记录
    private final static String FIX_PREFIX = "work/fix/";
    // 运行工作记录
    private final static String OPERATE_PREFIX = "work/operate/";
    // 清理工作记录
    private final static String CLEAN_PREFIX = "work/clean/";
    // 浇筑工作记录
    private final static String CASTING_PREFIX = "work/casting/";
    // 导杆编号管理
    private final static String ANODE_CODE_PREFIX = "manage/anodeCode/";
    // 阳极库存管理
    private final static String INV_ANODE_PREFIX = "manage/invAnode/";
    // 厂家信息
    private final static String PRODUCER_INFO_PREFIX = "manage/producerInfo/";
    // 极号信息
    private final static String POLE_INFO_PREFIX = "manage/poleInfo/";
    // 槽号信息
    private final static String SLOT_INFO_PREFIX = "manage/slotInfo/";
    // 工单信息
    private final static String ORDER_PREFIX = "work/order/";
    // 工单消息信息
    private final static String NOTICE_PREFIX = "system/notice/";
    // 报表模块
    private final static String REPORT_PREFIX = "report/";
    // 数据字典模块
    private final static String DICT_DATA_PREFIX = "system/dict/data/";
    // 字典类型模块
    private final static String DICT_TYPE_PREFIX = "system/dict/";
    // 文件类型接口
    private final static String FILE_PREFIX = "system/file/";
    // 部门接口
    private final static String DEPT_PREFIX = "system/dept/";
    // 阳极在位情况接口
    private final static String OPERATE_ANODE_PREFIX = "work/operate/anode/";
    // 用户接口
    private final static String USER_PREFIX = "/user/";
    // 工作记录接口
    private final static String RECORD_PREFIX = "/record/";

    @Autowired
    private TemplateProperty uploadProperty;
    @Autowired
    private ISysDictTypeService sysDictTypeService;
    @Autowired
    private IWorkBlockService workBlockService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IWorkOperateAnodeService workOperateAnodeService;
    @Autowired
    private Map<String, ISysFileService> fileServiceMap;
    @Autowired
    private IProducerInfoService producerInfoService;
    @Autowired
    private IInvAnodeService invAnodeService;
    @Autowired
    private IWorkCastingService workCastingService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private IWorkCleanService workCleanService;
    @Autowired
    private IAnodeCodeService anodeCodeService;
    @Autowired
    private ISlotInfoService slotInfoService;
    @Autowired
    private IPoleInfoService poleInfoService;
    @Autowired
    private IWorkOperateService workOperateService;
    @Autowired
    private IWorkFixService workFixService;
    @Autowired
    private IWorkCarService workCarService;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private IWorkOrderService workOrderService;
    @Autowired
    private ISysNoticeService noticeService;
    @Autowired
    private IWorkOperateDetailService workOperateDetailService;
    @Autowired
    private IWorkFixDetailService workFixDetailService;
    @Autowired
    private IRepInfoService repInfoService;
    @Autowired
    private IInvAnodeInputInfoService invAnodeInputInfoService;
    @Autowired
    private BCryptPasswordEncoder encode;
    @Autowired
    private JwtUtils jwtUtils;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    /* ================ 用户信息 =====================*/
    @ResponseBody
    @GetMapping(USER_PREFIX + "getCurrentUser")
    @ApiOperation("用户--获取当前用户信息")
    public Result getCurrentUserObj() {
        return Result.success(getCurrentUser());
    }

    @ResponseBody
    @PutMapping(USER_PREFIX + "edit")
    @ApiOperation("用户--修改用户信息")
    public Result editUser(@RequestBody SysUser sysUser) {
        log.info("当前修改的用户密码：" + sysUser.getPassword());
        if (sysUser.getPassword() != null) {
            String pwd = this.encode.encode(sysUser.getPassword());
            log.info(pwd);
            sysUser.setPassword(pwd);
        }
        boolean result = sysUserService.update(sysUser);
        if (result) {
            return Result.success(sysUserService.getById(sysUser.getUserId()));
        }
        return Result.failure("修改用户信息失败");
    }

    //获取当前用户
    private SysUser getCurrentUser() {
        return sysUserService.getById(getCurrentUserId());
    }

    //获取当前用户id
    private String getCurrentUserId() {
        return jwtUtils.getUserNameFromToken(ServletUtil.getHeader(tokenHeader));
    }

    /* ================ 碳块工作流程 =====================*/
    @ResponseBody
    @ApiOperation("碳块--列表")
    @GetMapping(BLOCK_PREFIX + "data")
    public ResultTable blockList(@ModelAttribute WorkBlock workBlock, PageDomain pageDomain) {
        PageInfo<WorkBlock> pageInfo = workBlockService.selectWorkBlockPage(workBlock, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @ResponseBody
    @ApiOperation("碳块--新增")
    @PostMapping(BLOCK_PREFIX + "save")
    public Result blockSave(@RequestBody WorkBlock workBlock) {
        if (workBlock.getQualifiedNum() == null && workBlock.getUnqualifiedNum() == null && workBlock.getDefectNum() == null) {
            return Result.failure("请完整填写数据 (查看合格数、降级数、退货数是否为空)");
        }
        SysUser sysUser = getCurrentUser();
        workBlock.setCreateTime(LocalDateTime.now());
        workBlock.setCreateBy(sysUser.getUserId());
        workBlock.setCreateName(sysUser.getRealName());
        workBlock.setId(SequenceUtil.makeStringId());
        return decide(workBlockService.insertWorkBlock(workBlock));
    }

    @ResponseBody
    @ApiOperation("碳块--批量删除")
    @DeleteMapping(BLOCK_PREFIX + "batchRemove")
    @PreAuthorize("hasPermission('/work/block/remove','work:block:remove')")
    public Result blockBatchRemove(String ids) {
        return decide(workBlockService.deleteWorkBlockByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @ApiOperation("碳块--id删除")
    @DeleteMapping(BLOCK_PREFIX + "remove/{id}")
    @PreAuthorize("hasPermission('/work/block/remove','work:block:remove')")
    public Result blockRemove(@PathVariable("id") String id) {
        return decide(workBlockService.deleteWorkBlockById(id));
    }

    /* ================ 车队工作流程 =====================*/
    @ResponseBody
    @ApiOperation("车队--车队记录列表")
    @GetMapping(CAR_PREFIX + "data")
    public ResultTable carList(@ModelAttribute WorkCar workCar, PageDomain pageDomain) {
        PageInfo<WorkCar> pageInfo = workCarService.selectWorkCarPage(workCar, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @ResponseBody
    @ApiOperation("车队--车队记录保存")
    @PostMapping(CAR_PREFIX + "save")
    public Result carSave(@RequestBody WorkCar workCar) {
        SysUser sysUser = getCurrentUser();
        workCar.setCreateTime(LocalDateTime.now());
        workCar.setCreateBy(sysUser.getUserId());
        workCar.setCreateName(sysUser.getRealName());
        workCar.setId(SequenceUtil.makeStringId());
        return decide(workCarService.insertWorkCar(workCar));
    }

    @ResponseBody
    @ApiOperation("车队--车队工作记录批量刪除")
    @DeleteMapping(CAR_PREFIX + "batchRemove")
    public Result carBatchRemove(String ids) {
        return decide(workCarService.deleteWorkCarByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @DeleteMapping(CAR_PREFIX + "remove/{id}")
    @ApiOperation("车队--根据车队记录id 删除")
    public Result carRemove(@PathVariable("id") String id) {
        return decide(workCarService.deleteWorkCarById(id));
    }

    /* ================ 检修工作流程 =====================*/

    @ResponseBody
    @ApiOperation("检修--列表")
    @GetMapping(FIX_PREFIX + "data")
    public ResultTable fixList(@ModelAttribute WorkFix workFix, PageDomain pageDomain) {
        PageInfo<WorkFix> pageInfo = workFixService.selectWorkFixPage(workFix, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @ResponseBody
    @ApiOperation("检修--新增")
    @PostMapping(FIX_PREFIX + "save")
    public Result fixSave(@RequestBody WorkFix workFix) {
        SysUser sysUser = getCurrentUser();
        workFix.setCreateTime(LocalDateTime.now());
        workFix.setCreateBy(sysUser.getUserId());
        workFix.setCreateName(sysUser.getRealName());
        workFix.setId(SequenceUtil.makeStringId());
        return decide(workFixService.insertWorkFix(workFix));
    }

    @ResponseBody
    @ApiOperation("检修--批量新增")
    @PostMapping(FIX_PREFIX + "fixBatchsave")
    public Result fixBatchSave(@RequestBody WorkFixDto dto) {
        SysUser sysUser = getCurrentUser();
        try {
            return Result.success(workFixService.batchInsertWorkFix(dto, sysUser));
        } catch (Exception e) {
            return Result.failure(e.getMessage());
        }
    }

    @ResponseBody
    @ApiOperation("检修--批量删除")
    @DeleteMapping(FIX_PREFIX + "batchRemove")
    public Result fixBatchRemove(String ids) {
        return decide(workFixService.deleteWorkFixByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @ApiOperation("检修--id删除")
    @DeleteMapping(FIX_PREFIX + "remove/{id}")
    public Result fixRemove(@PathVariable("id") String id) {
        return decide(workFixService.deleteWorkFixById(id));
    }

    /* ================ 运行工作流程 =====================*/
    @ResponseBody
    @ApiOperation("运行--列表")
    @GetMapping(OPERATE_PREFIX + "data")
    public ResultTable operateList(@ModelAttribute WorkOperate workOperate, PageDomain pageDomain) {
        PageInfo<WorkOperate> pageInfo = workOperateService.selectWorkOperatePage(workOperate, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @ResponseBody
    @ApiOperation("运行--新增")
    @PostMapping(OPERATE_PREFIX + "save")
    @Logging
    public Result operateSave(@RequestBody WorkOperate workOperate) {
        SysUser sysUser = getCurrentUser();
        workOperate.setCreateTime(LocalDateTime.now());
        workOperate.setCreateBy(sysUser.getUserId());
        workOperate.setCreateName(sysUser.getRealName());
        workOperate.setId(SequenceUtil.makeStringId());
        try {
            Result result = jumpOperate(OperateAnodeDto.builder()
                    .slotId(workOperate.getSlotId())
                    .poleId(workOperate.getPoleId())
                    .anodeCode(workOperate.getAnodeCode())
                    .type(workOperate.getOperateType()).build(),true);
            if (result.getCode()!=200) {
                return result;
            }
            workOperateService.insertWorkOperate(workOperate);
        } catch (BusinessException e) {
            return Result.failure(e.getMessage());
        }
        return Result.success();
    }


    @ResponseBody
    @ApiOperation("运行--工单列表")
    @GetMapping(OPERATE_PREFIX + "orderList")
    public Result operateOrderList() {
        SysUser sysUser = getCurrentUser();
        WorkOrder workOrder = new WorkOrder();
        workOrder.setAccepter(sysUser.getUserId());
        List<WorkOrder> result = workOrderService.selectWorkOrderList(workOrder).stream().
                filter(e -> !e.getStatus().equals("over") && !e.getStatus().equals("delete")).collect(Collectors.toList());
        return Result.success(result);
    }

    @ResponseBody
    @ApiOperation("运行--批量删除")
    @DeleteMapping(OPERATE_PREFIX + "batchRemove")
    public Result operateBatchRemove(String ids) {
        return decide(workOperateService.deleteWorkOperateByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @ApiOperation("运行--id删除")
    @DeleteMapping(OPERATE_PREFIX + "remove/{id}")
    public Result operateRemove(@PathVariable("id") String id) {
        return decide(workOperateService.deleteWorkOperateById(id));
    }

    /**
     * @param dto
     * @return
     */
    @ResponseBody
    @ApiOperation("运行--判断是否可以运行操作")
    @PostMapping(OPERATE_PREFIX + "check")
    public Result checkOperate(@RequestBody OperateAnodeDto dto) {
        return jumpOperate(dto,false);
    }

    private Result jumpOperate(OperateAnodeDto dto,boolean type) {
        Map map = new HashMap();
        String code = dto.getAnodeCode();
        String slotId = dto.getSlotId();
        String poleId = dto.getPoleId();
        map.put("anodeCode", code);
        map.put("slotId", slotId);
        map.put("poleId", poleId);
        if ("in".equals(dto.getType())) {
            if (StringUtils.isNotEmpty(dto.getAnodeCode())) {
                AnodeCode anodeCode = anodeCodeService.selectByCode(dto.getAnodeCode());
                if (anodeCode == null) {
                    return Result.failure("当前的编号不存在");
                }
            }

            if (StringUtil.isNotEmpty(slotId) && StringUtil.isNotEmpty(poleId)) {
                WorkOperateAnode anode = workOperateAnodeService.findBySlotAndPole(map);
                if(anode != null && "1".equals(anode.getStatus())){
                    OperateAnodeVO vo = new OperateAnodeVO();
                    vo.setStatus(anode.getStatus());
                    vo.setAnodeCode(anode.getAnodeCode());
                    vo.setSlotNo(anode.getSlotNo());
                    vo.setPoleNo(anode.getPoleNo());
                    return Result.failure("不允许操作，" + "当前槽号: " + anode.getSlotNo() +
                            ",极号：" + anode.getPoleNo() + ",导杆编号：" + anode.getAnodeCode(), vo);
                }
                if(StringUtils.isEmpty(dto.getAnodeCode())){
                    return Result.success("可以操作");
                }
            }
            WorkOperateAnode anode = workOperateAnodeService.findByCode(map);
            if (anode != null && "1".equals(anode.getStatus())) {
                OperateAnodeVO vo = new OperateAnodeVO();
                vo.setStatus(anode.getStatus());
                vo.setAnodeCode(anode.getAnodeCode());
                vo.setSlotNo(anode.getSlotNo());
                vo.setPoleNo(anode.getPoleNo());
                return Result.failure("不允许操作，" + "当前槽号: " + anode.getSlotNo() +
                        ",极号：" + anode.getPoleNo() + ",导杆编号：" + anode.getAnodeCode(), vo);
            }
        } else {
            if (StringUtil.isNotEmpty(code) && StringUtil.isNotEmpty(slotId) && StringUtil.isNotEmpty(poleId) && !type) {
                return Result.failure("阳极编号与槽号极号仅能选择一组输入");
            }
            WorkOperateAnode anode = workOperateAnodeService.findByParams(map);
            if (StringUtil.isNotEmpty(code) && anode == null) {
                return Result.failure("不允许操作，当前的编号没有绑定槽号极号");
            }
            if (StringUtil.isNotEmpty(slotId) && StringUtil.isNotEmpty(poleId) && anode == null) {
                return Result.failure("不允许操作，当前的槽号极号未绑定阳极");
            }
            if (anode != null && "0".equals(anode.getStatus())) {
                OperateAnodeVO vo = new OperateAnodeVO();
                vo.setStatus(anode.getStatus());
                vo.setAnodeCode(anode.getAnodeCode());
                vo.setSlotNo(anode.getSlotNo());
                vo.setPoleNo(anode.getPoleNo());
                if (StringUtil.isNotEmpty(code)) {
                    return Result.failure("不允许操作，当前的编号没有绑定槽号极号");
                }
                if (StringUtil.isNotEmpty(slotId) && StringUtil.isNotEmpty(poleId)) {
                    return Result.failure("不允许操作，当前的槽号极号未绑定阳极");
                }
                return Result.failure("不允许操作", vo);
            }
            return Result.success("可以操作", anode);
        }
        return Result.success("可以操作");
    }

    /* ================ 清理工作流程 =====================*/
    @ResponseBody
    @ApiOperation("清理--列表")
    @GetMapping(CLEAN_PREFIX + "data")
    public ResultTable cleanList(@ModelAttribute WorkClean workClean, PageDomain pageDomain) {
        PageInfo<WorkClean> pageInfo = workCleanService.selectWorkCleanPage(workClean, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @ResponseBody
    @ApiOperation("清理--新增")
    @PostMapping(CLEAN_PREFIX + "save")
    public Result cleanSave(@RequestBody WorkClean workClean) {
        SysUser sysUser = getCurrentUser();
        workClean.setCreateTime(LocalDateTime.now());
        workClean.setCreateBy(sysUser.getUserId());
        workClean.setCreateName(sysUser.getRealName());
        workClean.setId(SequenceUtil.makeStringId());
        return decide(workCleanService.insertWorkClean(workClean));
    }

    @ResponseBody
    @ApiOperation("清理--批量新增")
    @PostMapping(CLEAN_PREFIX + "batchSave")
    public Result cleanSave(@RequestBody WorkCleanDto dto) {
        SysUser sysUser = getCurrentUser();
        try {
            return Result.success(workCleanService.batchInsertWorkClean(dto, sysUser));
        } catch (Exception e) {
            return Result.failure(e.getMessage());
        }
    }

    @ResponseBody
    @ApiOperation("清理--批量id删除")
    @DeleteMapping(CLEAN_PREFIX + "batchRemove")
    public Result cleanBatchRemove(String ids) {
        return decide(workCleanService.deleteWorkCleanByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @ApiOperation("清理--id删除")
    @DeleteMapping(CLEAN_PREFIX + "remove/{id}")
    public Result cleanRemove(@PathVariable("id") String id) {
        return decide(workCleanService.deleteWorkCleanById(id));
    }

    /* ================ 浇筑工作流程 =====================*/
    @ResponseBody
    @ApiOperation("浇筑--列表")
    @GetMapping(CASTING_PREFIX + "data")
    public ResultTable castingList(@ModelAttribute WorkCasting workCasting, PageDomain pageDomain) {
        PageInfo<WorkCasting> pageInfo = workCastingService.selectWorkCastingPage(workCasting, pageDomain);
        //for (WorkCasting casting : pageInfo.getList()) {
        //    SysDept dept = sysDeptService.getById(casting.getDeptId());
        //    casting.set(dept.getDeptName());
        //}
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    /*接口数据模板
     *  {"num":1,"operateType":"in","deptId":"1","deptName":"分公司","params":{"invAnodes":[{"anodeCode":"BHY100001","blockType":"650"}]},"furnaceNo":"F001","createName":"管理"}
     */
    @ResponseBody
    @ApiOperation("浇筑--新增")
    @PostMapping(CASTING_PREFIX + "save")
    public Result castingSave(@RequestBody WorkCasting casting) {
        //校验blocktype、anodeCode不能为空
        if (casting.getParams() != null && casting.getParams().get("invAnodes") != null) {
            List<Object> invAnodes = (List<Object>) casting.getParams().get("invAnodes");
            for (Object object : invAnodes) {
                InvAnode ia = BeanUtil.copyProperties(object, InvAnode.class);
                if (StringUtil.isEmpty(ia.getAnodeCode()) || StringUtil.isEmpty(ia.getBlockType())) {
                    return Result.failure("导杆编号或导杆类型不能为空");
                }
                // 浇筑入库的时候判断导杆是否使用，导杆未使用那么就不能够新增
                InvAnodeInputInfo info = invAnodeInputInfoService.selectByAnodeCode(ia.getAnodeCode());
                if (info != null) {
                    if ("0".equals(info.getStatus())) {
                        //当前的导杆还未使用过，重复入库
                        return Result.failure("阳极编号：" + ia.getAnodeCode() + " 重复入库");
                    }
                }
            }
        }
        SysUser sysUser = getCurrentUser();
        casting.setCreateTime(LocalDateTime.now());
        casting.setCreateBy(sysUser.getUserId());
        casting.setCreateName(sysUser.getUsername());
        casting.setId(SequenceUtil.makeStringId());
        return decide(workCastingService.insertWorkCasting(casting));
    }

    @ResponseBody
    @ApiOperation("浇筑--id批量删除")
    @DeleteMapping(CASTING_PREFIX + "batchRemove")
    public Result castingBatchRemove(String ids) {
        return decide(workCastingService.deleteWorkCastingByIds(Convert.toStrArray(ids)));
    }

    @ResponseBody
    @ApiOperation("浇筑--id删除")
    @DeleteMapping(CASTING_PREFIX + "remove/{id}")
    public Result castingRemove(@PathVariable("id") String id) {
        return decide(workCastingService.deleteWorkCastingById(id));
    }

    @ApiOperation("浇筑--判断是否重复入库")
    @GetMapping(CASTING_PREFIX + "useCheck")
    public Result useCheck(String anodeCode) {
        return invAnodeInputInfoService.useCheck(anodeCode) ? Result.success("通过") : Result.failure("当前导杆还未使用，不能重复入库");
    }

    /* ================ 导杆编号工作流程 =====================*/

    @ResponseBody
    @ApiOperation("阳极编号--阳极编号列表")
    @GetMapping(ANODE_CODE_PREFIX + "data")
    public ResultTable anodeCodeList(@ModelAttribute AnodeCode anodeCode, PageDomain pageDomain) {
        PageInfo<AnodeCode> pageInfo = anodeCodeService.selectAnodeCodePage(anodeCode, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    /* ================ 阳极库存工作流程 =====================*/
    @ApiOperation("阳极库存--阳极库存列表")
    @GetMapping(INV_ANODE_PREFIX + "data")
    public Result invAnodeList() {
        List<InvAnode> list = invAnodeService.selectInvAnodeList(null);
        List<InvAnodeVO> vos = new ArrayList<>();
        for (InvAnode invAnode : list) {
            InvAnodeVO vo = BeanUtil.copyProperties(invAnode, InvAnodeVO.class);
            vos.add(vo);
        }
        return Result.success(vos);
    }

    @ApiOperation("阳极库存--根据阳极编号获取阳极信息")
    @GetMapping(INV_ANODE_PREFIX + "findByAnodeCode")
    public Result findInvInfoByAnodeCode(String anodeCode) {
        InvAnode invAnode = invAnodeService.selectInvAnodeByAnodeCode(anodeCode);
        InvAnodeVO vo = BeanUtil.copyProperties(invAnode, InvAnodeVO.class);
        return Result.success(vo);
    }

    /* ================ 厂家信息 =====================*/
    @ResponseBody
    @ApiOperation("厂家--厂家信息列表")
    @GetMapping(PRODUCER_INFO_PREFIX + "data")
    public ResultTable producerInfoList(@ModelAttribute ProducerInfo producerInfo, PageDomain pageDomain) {
        PageInfo<ProducerInfo> pageInfo = producerInfoService.selectProducerInfoPage(producerInfo, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    /* ================ 极号信息 =====================*/
    @ApiOperation("极号--极号信息列表")
    @GetMapping(POLE_INFO_PREFIX + "data")
    public Result poleInfoList() {
        List<PoleInfo> list = poleInfoService.selectPoleInfoList(null);
        //改成前端渲染
        List<PoleInfoVO> vos = new ArrayList<>();
        for (PoleInfo info : list) {
            PoleInfoVO vo = BeanUtil.copyProperties(info, PoleInfoVO.class);
            SlotInfo slotInfo = slotInfoService.selectSlotInfoById(info.getSlotId());
            vo.setSlotNo(slotInfo.getSlotNo());
            vos.add(vo);
        }
        return Result.success(vos);
    }

    @ResponseBody
    @ApiOperation("极号--通过槽号Id获取极号信息")
    @GetMapping(POLE_INFO_PREFIX + "dataBySlotId")
    public Result selectBySlotId(String slotId) {
        List<PoleInfo> poleInfos = poleInfoService.selectBySlotId(slotId);
        List<PoleInfoVO> vos = new ArrayList<>();
        for (PoleInfo info : poleInfos) {
            PoleInfoVO vo = BeanUtil.copyProperties(info, PoleInfoVO.class);
            vos.add(vo);
        }
        return Result.success(vos);
    }

    /* ================ 槽号信息 =====================*/
    @ApiOperation("槽号--列表")
    @GetMapping(SLOT_INFO_PREFIX + "data")
    public Result slotInfoList() {
        List<SlotInfo> list = slotInfoService.selectSlotInfoList(null);
        List<SlotInfoVO> vos = new ArrayList<>();
        for (SlotInfo slotInfo : list) {
            SlotInfoVO vo = BeanUtil.copyProperties(slotInfo, SlotInfoVO.class);
            vos.add(vo);
        }
        return Result.success(vos);
    }

    @ResponseBody
    @ApiOperation("槽号--通过部门id查列表")
    @GetMapping(SLOT_INFO_PREFIX + "dataByDeptId")
    public Result slotInfoDataByDeptId(String deptId) {
        SlotInfo slotInfo = new SlotInfo();
        slotInfo.setDeptId(deptId);
        return Result.success(slotInfoService.selectSlotInfoList(slotInfo));
    }

    /* ================ 字典类型信息 =====================*/

    @GetMapping(DICT_DATA_PREFIX + "data")
    @ApiOperation("字典类型--列表")
    public ResultTable data(SysDictData sysDictData, PageDomain pageDomain) {
        PageInfo<SysDictData> pageInfo = sysDictDataService.page(sysDictData, pageDomain);
        return pageTable(pageInfo.getList(), pageInfo.getTotal());
    }

    @GetMapping(DICT_DATA_PREFIX + "selectByCode")
    @ApiOperation("字典类型--根据typeCodec查找列表")
    public Result selectByCode(String typeCode) {
        List<SysDictDataVO> list = sysDictDataService.findByTypeCode(typeCode);
        return success(list);
    }

    /* ================ 数据字典信息 =====================*/
    @GetMapping(DICT_TYPE_PREFIX + "list")
    @ApiOperation("数据字典--列表")
    public Result list() {
        List<SysDictType> list = sysDictTypeService.list(null);
        List<SysDictTypeVO> vos = new ArrayList<>();
        for (SysDictType sysDictType : list) {
            SysDictTypeVO vo = new SysDictTypeVO();
            BeanUtils.copyProperties(sysDictType, vo);
            vos.add(vo);
        }
        return Result.success(vos);
    }

    @GetMapping(DICT_TYPE_PREFIX + "typeCode")
    @ApiOperation("数据字典--根据typeCode查找列表")
    public Result getByCode(String typeCode) {
        List<SysDictTypeVO> list = sysDictTypeService.selectByCode(typeCode);
        return Result.success(list);
    }

    /* ================ 文件上传信息 =====================*/
    @PostMapping(FILE_PREFIX + "upload")
    @ApiOperation("文件--文件上传")
    public Result upload(@RequestParam("file") MultipartFile file) {
        String result = getFileService().upload(file);
        if (Strings.isNotBlank(result)) {
            return Result.success(0, "上传成功", result);
        } else {
            return Result.failure("上传失败");
        }
    }

    @GetMapping(FILE_PREFIX + "download/{id}")
    @ApiOperation("文件--获取文件流")
    public void download(@PathVariable("id") String id) {
        getFileService().download(id);
    }

    @DeleteMapping(FILE_PREFIX + "remove/{id}")
    @ApiOperation("文件--文件删除")
    public Result remove(@PathVariable("id") String id) {
        boolean result = getFileService().remove(id);
        return Result.decide(result, "删除成功", "删除失败");
    }

    @Transactional(rollbackFor = Exception.class)
    @DeleteMapping("batchRemove/{ids}")
    @ApiOperation("文件--批量文件删除")
    public Result batchRemove(@PathVariable("ids") String ids) {
        for (String id : ids.split(CommonConstant.COMMA)) {
            getFileService().remove(id);
        }
        return Result.success("删除成功");
    }

    //获取文件服务实体
    private ISysFileService getFileService() {
        ISysFileService fileService = null;
        if (uploadProperty.isFtpUse()) {
            fileService = this.fileServiceMap.get("SysFileFTPServiceImpl");
        } else {
            fileService = this.fileServiceMap.get("SysFileServiceImpl");
        }
        return fileService;
    }

    /* ================ 部门信息 =====================*/
    @GetMapping(DEPT_PREFIX + "data")
    @ApiOperation("部门--列表")
    public Result data() {
        List<SysDept> data = sysDeptService.list(null);
        return Result.success(data);
    }

    @GetMapping(DEPT_PREFIX + "findByCurrentUser")
    @ApiOperation("部门--根据当前登录用户获取部门信息")
    public Result findByUserId() {
        SysDeptVO data = sysDeptService.findByUserId(getCurrentUserId());
        return Result.success(data);
    }

    @GetMapping(DEPT_PREFIX + "findInfoByCurrentUser")
    @ApiOperation("部门--获取当前用户的厂区工区班组")
    public Result findInfoByCurrentUser() {
        return Result.success(sysDeptService.getMapByCurrentUserDeptId(getCurrentUser().getDeptId()));
    }

    @GetMapping(DEPT_PREFIX + "findParentByCurrentUser")
    @ApiOperation("部门--获取当前用户的部门父级信息")
    public Result findParentByCurrentUser() {
        SysDept dept = sysDeptService.getById(getCurrentUser().getDeptId());
        SysDeptVO vo = new SysDeptVO();
        vo.setDeptCode(dept.getDeptCode());
        vo.setDeptId(dept.getDeptId());
        return Result.success(sysDeptService.findParentByDeptCode(vo));
    }

    @GetMapping(DEPT_PREFIX + "findChildByCurrentUser")
    @ApiOperation("部门--获取当前用户部门子级信息")
    public Result findChildByCurrentUser() {
        SysDept dept = sysDeptService.getById(getCurrentUser().getDeptId());
        SysDeptVO vo = new SysDeptVO();
        vo.setDeptCode(dept.getDeptCode());
        vo.setDeptId(dept.getDeptId());
        return Result.success(sysDeptService.findChildByDeptCode(vo));
    }

    @PostMapping(DEPT_PREFIX + "findParentByDeptCode")
    @ApiOperation("部门--根据部门代码获取部门父级信息")
    public Result findParentByDeptCode(@RequestBody SysDeptVO vo) {
        return Result.success(sysDeptService.findParentByDeptCode(vo));
    }

    @PostMapping(DEPT_PREFIX + "findChildByDeptCode")
    @ApiOperation("部门--根据部门代码获取部门子级信息")
    public Result findChildByDeptCode(@RequestBody SysDeptVO vo) {
        List<SysDeptVO> childByDeptCode = sysDeptService.findChildByDeptCode(vo);
        return Result.success(childByDeptCode);
    }

    @GetMapping(DEPT_PREFIX + "findDeptList")
    @ApiOperation("部门--根据部门代号获取相应的部门列表（接收人：accept,配送人：send,出库人：out,所有用户：all)")
    public Result findDeptList(String deptCode) {
        return Result.success(sysDeptService.findDeptList(getDeptCode(deptCode)));

    }

    @GetMapping(DEPT_PREFIX + "findAcceptList")
    @ApiOperation("部门--获取收货/取货部门的id和部门链条 （收货部门：operate,取货部门：casting)")
    public Result findAcceptList(String deptCode) {
        return Result.success(sysDeptService.findAcceptDeptList(deptCode));
    }

    public String getDeptCode(String deptCode) {
        Map<String, String> map = new HashMap<>();
        map.put("accept", "operate");
        map.put("send", "car_class");
        map.put("out", "casting");
        map.put("all", "");
        return map.get(deptCode);
    }

    /* ================ 阳极在位情况信息 =====================*/

    @GetMapping(OPERATE_ANODE_PREFIX + "data")
    @ApiOperation("阳极在位情况--列表")
    public Result operateAnodeList() {
        List<WorkOperateAnode> list = workOperateAnodeService.selectWorkOperateAnodeList(null);
        return Result.success(list);
    }

    @GetMapping(OPERATE_ANODE_PREFIX + "getByAnodeCode")
    @ApiOperation("阳极在位情况--通过阳极编号获取在位情况")
    public Result findByAnodeCode(String anodeCode) {
        WorkOperateAnode woAnode = workOperateAnodeService.findOperateAnodeByAnodeCode(anodeCode);
        return Result.success(woAnode);
    }

    /* ================ 工单信息 =====================*/

    @ResponseBody
    @GetMapping(ORDER_PREFIX + "data")
    @ApiOperation("工单--列表")
    public Result orderList(PageDomain pageDomain) {
        PageInfo<WorkOrder> pageInfo = workOrderService.selectWorkOrderPage(null, pageDomain);
        return Result.success(pageInfo.getList());
    }

    @ResponseBody
    @GetMapping(ORDER_PREFIX + "getOrderList")
    @ApiOperation("工单--获取工单申请信息列表")
    public Result getOrderList(PageDomain pageDomain) {
        PageInfo<WorkOrder> pageInfo = workOrderService.getOrderList(null, pageDomain);
        return Result.success(pageInfo.getList());
    }

    @ResponseBody
    @PostMapping(ORDER_PREFIX + "save")
    @ApiOperation("工单--保存")
    public Result orderSave(@RequestBody WorkOrder workOrder) {
        //判断当前的库存数量是否满足工单的需求
        int lowerNum = invAnodeService.selectCurrNum("620");
        if (workOrder.getLowNum() > lowerNum) {
            return Result.failure("当前阳极规格为620的库存数量不足，剩余数量为" + lowerNum + "请重新输入请减少数量");
        }
        int highNum = invAnodeService.selectCurrNum("650");
        if (workOrder.getHighNum() > highNum) {
            return Result.failure("当前阳极规格为650的库存数量不足，剩余数量为" + highNum + "请重新输入请减少数量");
        }
        int otherNum = invAnodeService.selectCurrNum("其他");
        if (workOrder.getOtherNum() > otherNum) {
            return Result.failure("当前阳极规格为其他的库存数量不足，剩余数量为" + otherNum + "请重新输入请减少数量");
        }
        SysUser currentUser = getCurrentUser();
        workOrder.setCreateBy(currentUser.getUserId());
        workOrder.setCreateName(currentUser.getRealName());
        workOrder.setCreateTime(LocalDateTime.now());
        workOrder.setId(SequenceUtil.makeStringId());
        int result = workOrderService.insertWorkOrder(workOrder);
        if (result > 0) {
            return Result.success(workOrderService.selectWorkOrderById(workOrder.getId()));
        }
        return Result.failure("工单保存出错，请再试一次");
    }

    @ResponseBody
    @PutMapping(ORDER_PREFIX + "update")
    @ApiOperation("工单--修改")
    public Result orderUpdate(@RequestBody WorkOrder workOrder) {
        //如果此时的工单状态已更改为删除的话就不能进行核验操作了
        WorkOrder order = workOrderService.selectWorkOrderById(workOrder.getId());
        if (workOrder.getParams() != null && workOrder.getParams().get("invAnodes") != null) {
            //判断需求数量和扫码的数量是否匹配
            List<Map<String, String>> invAnodes = (List) workOrder.getParams().get("invAnodes");
            List<InvAnode> list = new ArrayList<InvAnode>();
            for (Map<String, String> map : invAnodes) {
                InvAnode invAnode = new InvAnode();
                String anodeCode = map.get("anodeCode");
                String blockType = map.get("blockType");
                if (!StringUtils.isEmpty(anodeCode)) {
                    invAnode.setAnodeCode(anodeCode);
                }
                if (!StringUtils.isEmpty(blockType)) {
                    invAnode.setBlockType(blockType);
                }
                if (!StringUtils.isEmpty(anodeCode) && !StringUtils.isEmpty(blockType)) {
                    list.add(invAnode);
                }
            }
            List<InvAnode> highCollect = list.stream().filter(e -> e.getBlockType().equals("650")).collect(Collectors.toList());
            List<InvAnode> LowerCollect = list.stream().filter(e -> e.getBlockType().equals("620")).collect(Collectors.toList());
            if (order.getHighNum() != highCollect.size()) {
                return Result.failure("650的导杆数量和需求数量不对");
            }
            if (order.getLowNum() != LowerCollect.size()) {
                return Result.failure("620的导杆数量和需求数量不对");
            }
        }
        //判断工单是否删除
        int result = 0;
        if ("0".equals(order.getEnable())) {
            return Result.failure("当前工单：{} 已失效，请查看最新消息并重新操作", workOrder.getId());
        }
        if ("over".equals(workOrder.getStatus())) {
            order.setStatus(workOrder.getStatus());
            result = workOrderService.updateWorkOrder(order);
        } else {
            result = workOrderService.updateWorkOrder(workOrder);
        }
        Result decide = decide(result);
        //组装返回成功的信息
        if (200 == decide.getCode()) {
            String message = "";
            if ("send".equals(workOrder.getStatus())) {
                message = "当前工单: " + workOrder.getId() + " 核验完成，当前状态为：配送中";
            } else {
                message = "当前工单: " + workOrder.getId() + " 验收完成，当前状态为：完成";
            }
            String msg = message + "," + decide.getMsg();
            decide.setData(workOrderService.selectWorkOrderById(workOrder.getId()));
            decide.setMsg(msg);
        }
        return decide;
    }

    @ResponseBody
    @DeleteMapping(ORDER_PREFIX + "/remove/{id}")
    @ApiOperation("工单--删除")
    public Result orderRemove(@PathVariable("id") String id) {
        //如果当前的订单的状态是核验中（check）就可以删除
        WorkOrder workOrder = workOrderService.selectWorkOrderById(id);
        if ("check".equals(workOrder.getStatus())) {
            workOrder.setEnable("0");
            workOrder.setStatus("delete");
        } else {
            return Result.failure("删除失败，当前工单已经完成验收，正在配送中，不能删除");
        }
        return decide(workOrderService.updateWorkOrder(workOrder));
    }

    @GetMapping(ORDER_PREFIX + "orderStatus")
    @ApiOperation("工单--根据工单号获取工单的信息")
    public Result orderStatus(String orderId) {
        return Result.success(workOrderService.selectWorkOrderById(orderId));
    }

    @GetMapping(ORDER_PREFIX + "getAnodeCode")
    @ApiOperation("工单--车队配送根据阳极编号获取类型")
    public Result orderGetAnodeCode(String anodeCode) {
        //查询当前工单中是否包含了该编码
        if (!invAnodeService.checkAnodeCodeIsValid(anodeCode)) {
            return Result.failure("当前编号已经存在其他工单里面，不能操作");
        }
        InvAnodeVO vo = invAnodeService.findAnodeCode(anodeCode);
        if (vo == null) {
            return Result.failure("当前编号" + anodeCode + "不在库存中");
        }
        return Result.success(vo);
    }

    /* ================ 消息信息 =====================*/
    @PutMapping(NOTICE_PREFIX + "updateStatus")
    @ApiOperation("消息--更新消息状态已读未读 status(是否读取) 1表示已读，0表示未读")
    public Result updateStatus(@RequestBody NoticeStatus status) {
        return Result.success(noticeService.updateStatus(status));
    }

    @GetMapping(NOTICE_PREFIX + "data")
    @ApiOperation("消息--获取消息列表 status(是否读取) 1表示已读，0表示未读")
    public Result noticeData(@RequestParam(value = "status", required = false) String status) {
        SysNotice sysNotice = new SysNotice();
        String currentUserId = getCurrentUserId();
        sysNotice.setStatus(status);
        sysNotice.setAccept(currentUserId);
        return Result.success(noticeService.list(sysNotice));
    }


    @GetMapping(NOTICE_PREFIX + "unReadNum")
    @ApiOperation("消息--获取未读消息数 0表示未读")
    public Result noticeUnReadNum() {
        SysNotice sysNotice = new SysNotice();
        String currentUserId = getCurrentUserId();
        sysNotice.setAccept(currentUserId);
        return Result.success(noticeService.selectSysNoticeList(sysNotice).size());
    }

    /* ================ 工作记录 =====================*/

    @ResponseBody
    @ApiOperation("工作记录--车队根据工单id获取车队信息")
    @GetMapping(RECORD_PREFIX + "getCarDetailByOrderId")
    public Result getByOrderId(String orderId) {
        return Result.success(workCarService.getByOrderId(orderId));
    }

    @ResponseBody
    @ApiOperation("工作记录--检修根据检修id获取检修详情")
    @GetMapping(RECORD_PREFIX + "getFixDeatilByFixId")
    public Result getFixDetailByFixId(String fixId) {
        WorkFix workFix = workFixService.selectWorkFixById(fixId);
        if (workFix.getIsScrap().equals("1")) {
            return Result.success(workFix);
        }
        return Result.success(workFixDetailService.getFixDetailByFixId(fixId));
    }

    @ResponseBody
    @ApiOperation("工作记录--运行根据运行id获取运行详情")
    @GetMapping(RECORD_PREFIX + "getOperateDetailByIdOrOrderId")
    public Result getOperateDetailById(@RequestParam(value = "operateId", required = false) String operateId, @RequestParam(value = "orderId", required = false) String orderId) {
        if (!StringUtil.isEmpty(operateId)) {
            return Result.success(workOperateDetailService.getDetailById(operateId));
        } else if (!StringUtil.isEmpty(orderId)) {
            return Result.success(workOperateService.findByOrderId(orderId));
        }
        return Result.success();
    }

    @ResponseBody
    @ApiOperation("工作记录--浇筑根据id获取出入库详情")
    @GetMapping(RECORD_PREFIX + "getCastingDetailById")
    public Result getCastingDetailById(String castingId) {
        return Result.success(invAnodeService.getCastingDetailById(castingId));
    }

    /* ================ 报表记录 =====================*/

    @GetMapping(REPORT_PREFIX + "List")
    @ApiOperation("获取个人权限报表列表")
    public Result reportList() {
        //根据当前的权限获取报表
        SysUser currentUser = getCurrentUser();
        SysDept dept = sysDeptService.getById(currentUser.getDeptId());
        //分公司 科室
        List<RepInfo> repInfos = repInfoService.selectRepInfoList(null);
        repInfos = repInfos.stream().filter(e -> !StringUtil.isEmpty(e.getDeptCode())).collect(Collectors.toList());
        if (dept.getDeptCode().equals("company") || dept.getDeptCode().contains("department")) {
            List<RepInfoVO> collect = repInfos.stream().map(x -> {
                RepInfoVO vo = new RepInfoVO();
                BeanUtil.copyProperties(x, vo);
                vo.setGid(String.valueOf(x.getId()));
                return vo;
            }).collect(Collectors.toList());
            return Result.success(collect);
        }

        List<RepInfo> result = repInfos.stream().filter(e -> e.getDeptCode().contains(dept.getDeptCode())).collect(Collectors.toList());
        List<RepInfoVO> collect = result.stream().map(x -> {
            RepInfoVO vo = new RepInfoVO();
            BeanUtil.copyProperties(x, vo);
            vo.setGid(String.valueOf(x.getId()));
            return vo;
        }).collect(Collectors.toList());
        return Result.success(collect);

    }
}
